Skip to content

feat: Release v0.17.0 — adds two major features: Copy/Move Test Cases Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes#147

Merged
therealbrad merged 106 commits intomainfrom
v0.17.0
Mar 22, 2026

Conversation

@therealbrad
Copy link
Contributor

@therealbrad therealbrad commented Mar 22, 2026

Description

Release v0.17.0 — adds two major features: Copy/Move Test Cases Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes.

Copy/Move Test Cases (Phases 29–33)

  • Three-step wizard dialog for copying or moving test cases between projects
  • Collision detection with skip/rename/overwrite strategies and preflight summary
  • Background worker with folder tree recreation, inline folder creation, and notification on completion
  • Bulk edit modal and context menu entry points
  • E2E API tests and component unit tests

Per-Prompt LLM Configuration (Phases 34–39)

  • New llmIntegrationId and modelOverride fields on PromptConfigPrompt schema
  • 3-tier resolution chain: prompt-level → project-level → system default via resolveIntegration
  • Admin prompt editor LLM selector and per-feature override UI on project AI Models page
  • Prompt config export/import API routes
  • Unit tests for resolution chain; E2E tests for LLM selector and per-feature overrides

Other

  • Audit logging added to syncWorker, forecastWorker, and testmoImportWorker
  • Performance: skip forecast DB writes when values unchanged
  • Bug fixes: Rules of Hooks ordering, JSX parse errors, TypeScript errors, lint cleanup

Related Issue

Closes #146
Closes #143
Closes #128
Closes #79

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement

How Has This Been Tested?

Describe the tests you ran to verify your changes:

  • Unit tests
  • Integration tests
  • E2E tests
  • Manual testing

Test Configuration:

  • OS: macOS
  • Browser (if applicable): Chrome
  • Node version: 22.x

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published
  • I have signed the CLA

Additional Notes

159 commits, 146 files changed, ~23k lines added across this milestone.

therealbrad and others added 30 commits March 20, 2026 09:30
Adds STACK, FEATURES, ARCHITECTURE, PITFALLS, and SUMMARY research
files for the cross-project copy/move milestone. Zero new dependencies
required; all implementation patterns map to existing auto-tag worker
and import route precedents.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add COPY_MOVE_QUEUE_NAME = "copy-move" constant to lib/queueNames.ts
- Add getCopyMoveQueue() lazy initializer to lib/queues.ts with attempts:1 (no retry)
- Re-export COPY_MOVE_QUEUE_NAME from lib/queues.ts
- Add copyMoveQueue to getAllQueues() return object
- Add worker:copy-move script to package.json
- Append pnpm worker:copy-move to the workers concurrently command
…y/move

- Create workers/copyMoveWorker.ts with full copy/move data carry-over
- Exports CopyMoveJobData, CopyMoveJobResult, processor, startWorker
- resolveSharedStepGroup: recreates SharedStepGroups in target with deduplication
  map; respects reuse/create_new resolution per user choice (DATA-08, DATA-09)
- resolveFieldValue: resolves Dropdown/MultiSelect option IDs by name across
  templates; drops values with no matching option (DATA-02)
- fetchTemplateFields: fetches field definitions separately to avoid 63-char
  PostgreSQL alias limit
- processor: validates multi-tenant context, pre-fetches folderMaxOrder before
  loop to avoid race conditions
- Per-case prisma.$transaction with steps, field values, attachments, tags,
  issues, versions, and comments (move only)
- Copy path: creates version 1 via createTestCaseVersionInTransaction (DATA-07)
- Move path: replicates all RepositoryCaseVersions rows with updated projectId
  (DATA-06), copies comments with repositoryCaseId: newCase.id
- Rollback on failure: deleteMany createdTargetIds (cascade handles children)
- Move soft-deletes source cases only after all copies succeed
- ES sync (bulk, post-loop) via syncRepositoryCaseToElasticsearch
- Redis cancellation support between cases via cancelKey helper
- concurrency: 1 (locked to prevent ZenStack v3 deadlocks)
- Graceful SIGTERM/SIGINT shutdown
- Create 28-01-SUMMARY.md documenting all tasks, decisions, and requirements
- Update STATE.md: phase 28 plan 01 complete, decisions recorded, metrics updated
- Update ROADMAP.md: phase 28 progress updated
- Mark DATA-01 through DATA-09 complete in REQUIREMENTS.md
- DATA-01: verify steps created in target with correct content and order
- DATA-02: verify Dropdown option IDs resolved by name (target 600, not source 500)
- DATA-03/04: verify tags and issues connected by global ID
- DATA-05: verify attachment rows created with same S3 URL
- DATA-06: verify move recreates all version rows with target projectId, preserving staticProjectId/Name
- DATA-07: verify copy creates version 1 via createTestCaseVersionInTransaction
- DATA-08: verify shared step groups recreated in target; deduplication across cases
- DATA-09: verify reuse/create_new resolution for name collisions (copy suffix)
- Rollback: verify deleteMany called on createdTargetIds when any case fails
- Cancellation: verify pre-start and between-case cancellation with rollback
- Move source deletion: verify updateMany called only after all copies succeed
- ES sync: non-fatal failure does not throw; syncs all created case IDs
- Created 28-02-SUMMARY.md with test coverage documentation
- Updated STATE.md: plan 02 complete, 14% progress, added test pattern decisions
- Updated ROADMAP.md: Phase 28 marked Complete (2 of 2 plans done)
…move endpoints

- preflightSchema with operation, caseIds, sourceProjectId, targetProjectId
- submitSchema with conflictResolution limited to skip/rename (no overwrite)
- submitSchema with sharedStepGroupResolution enum and optional target fields
- PreflightResponse interface with templateMismatch, workflowMappings, collisions fields
- GET /api/repository/copy-move/status/[jobId] polls BullMQ job state
- Uses getCopyMoveQueue() with multi-tenant isolation check
- Returns state, progress, result, failedReason, timestamps
- 7 unit tests covering auth, 503, 404, tenant isolation, completed/failed/active states
- 16 test cases covering: 401 unauth, 400 invalid body, 403 no source access,
  403 no target access, templateMismatch detection, canAutoAssignTemplates for
  ADMIN and PROJECTADMIN, workflowMappings name-match and default fallback,
  unmappedStates, collision detection, targetRepositoryId resolution,
  hasSourceDeleteAccess for move operation
… checks

- Auth check: 401 if no session
- Zod validation: 400 on invalid body
- Source/target project access via enhance(db, { user }): 403 on missing access
- Move delete access check via repositoryCases.findFirst
- Template compatibility: detects missingTemplates, templateMismatch flag
- canAutoAssignTemplates for ADMIN and PROJECTADMIN users
- Workflow state mapping with name-match and default fallback
- unmappedStates list for states falling back to default
- Collision detection via OR query on (name, className, source)
- Resolves targetRepositoryId from active repository
- Returns full PreflightResponse with all required fields
- SUMMARY.md: schemas + preflight route with 16 unit tests
- STATE.md: advanced to phase 29 plan 01 complete
- ROADMAP.md: phase 29 in progress (1/4 plans complete)
- REQUIREMENTS.md: COMPAT-01, COMPAT-03, COMPAT-04 marked complete
- POST /api/repository/copy-move/cancel/[jobId] handles job cancellation
- Uses getCopyMoveQueue() with multi-tenant isolation check
- Only job submitter (userId match) can cancel their own job
- Sets Redis key 'copy-move:cancel:{jobId}' EX 3600 for active jobs (matches worker)
- Calls job.remove() directly for waiting/delayed jobs
- 8 unit tests covering auth, 503, 404, tenant isolation, 403, finished, waiting, active states
- SUMMARY.md: 2 tasks, 4 files, 15 tests, 9m duration
- STATE.md: advance to plan 02 complete, add Redis cancel key decision
- ROADMAP.md: phase 29 progress updated (2/4 plans complete)
- REQUIREMENTS.md: BULK-03 marked complete
- Added project.userPermissions SPECIFIC_ROLE Project Admin create/delete rule
- Added project.assignedUsers PROJECTADMIN create/delete rule
- Matches pattern from CaseExportTemplateProjectAssignment (blueprint model)
- Enables project admins to auto-assign templates on copy/move submit
- 15 test cases covering auth, validation, permissions, auto-assign, resolve IDs, job enqueue
- Tests for both ADMIN and PROJECTADMIN auto-assign paths
- Tests for silent skip when regular user attempts auto-assign
- Tests for conflictResolution=overwrite rejection (schema enforced)
… enqueue (GREEN)

- POST /api/repository/copy-move validates with submitSchema (rejects overwrite)
- Enforces source read, target write, and move delete permissions via ZenStack enhance
- Admin and PROJECTADMIN users can auto-assign missing templates to target project
- Regular users silently skip auto-assign (no error)
- Resolves targetRepositoryId, targetTemplateId, targetDefaultWorkflowStateId when not provided
- Enqueues CopyMoveJobData to BullMQ with userId and tenantId
- Returns { jobId } on success; all 15 unit tests pass
- Created 29-03-SUMMARY.md with TDD deviation documentation
- Updated STATE.md position, decisions, metrics, and session
- Updated ROADMAP.md phase 29 progress (3/3 plans complete)
- Marked COMPAT-02 and BULK-01 requirements complete
therealbrad and others added 24 commits March 21, 2026 07:55
… duplicates

- Project picker: uses navigation.projects.dropdown.selectProject
- Folder picker: uses repository.cases.importWizard.page1.selectFolderPlaceholder
- Removed duplicate selectProject and selectFolder keys from components.copyMove

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- E2E: test folder tree copy recreates hierarchy with cases in correct folders
- E2E: test folder tree move soft-deletes source folders
- Docs: add folder context menu entry point section
- Docs: add Folder Tree Copy/Move section covering hierarchy, empty folders,
  merge behavior, and move cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Expanded table to show Copy vs Move columns for each data type
- Added "Data Not Included" section covering test run results, result
  field values, JUnit/automated results, cross-project links, and forecasts
- Updated Copy vs Move table to include comments difference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…jects

- Toolbar button, context menu item, bulk edit button, and folder menu
  all gated on canAddEdit AND projectCount > 1
- No point showing copy/move if user only has access to one project

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mentation

- Changed "JUnit/automated test results" to "Automated test results" for clarity.
- Ensured consistency in the description of data not transferred during copy or move operations.
Log CREATE events for each case created in target project and DELETE
events for source cases soft-deleted during move. Events include
sourceProjectId, targetProjectId, and jobId in metadata.

See #143 for the broader worker audit logging gap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Updated TreeView component to include hover text color changes for better visibility.
- Refactored Header component for improved readability and consistency in imports and JSX structure.
- Enhanced SearchIssuesDialog component with more descriptive class names for hover states.
- Added new "tools" terminology in English, Spanish, and French localization files.
- Introduced new folder action "copyMove" in localization files for better user guidance.
- Import captureAuditEvent from auditLog service
- Emit BULK_CREATE audit event on successful import completion
- Event includes entityProgress counts and duration metadata
- Best-effort (.catch(() => {})) — never blocks the import job
- syncWorker: BULK_UPDATE events for sync-issues and sync-project-issues
- syncWorker: UPDATE event for refresh-issue
- forecastWorker: UPDATE event for each milestone auto-completed with isCompleted change
- All calls use .catch(() => {}) pattern — best-effort, never blocks jobs
…event

- Use jobId (string parameter) instead of job.id (BullMQ Job not in scope)
- processImportMode function receives jobId as parameter, not the BullMQ Job object
- SUMMARY.md with task commits, deviations, and decisions
Missing mock caused all 15 Cases component tests to crash during render.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- updateRepositoryCaseForecast: fetch current values, only update if different
- updateTestRunForecast: compare before writing for both clear and set paths
- Reduces unnecessary DB writes during scheduled forecast recalculations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(260321-fk3): add audit logging to testmoImportWorker

- Import captureAuditEvent from auditLog service
- Emit BULK_CREATE audit event on successful import completion
- Event includes entityProgress counts and duration metadata
- Best-effort (.catch(() => {})) — never blocks the import job

* feat(260321-fk3): add audit logging to syncWorker and forecastWorker

- syncWorker: BULK_UPDATE events for sync-issues and sync-project-issues
- syncWorker: UPDATE event for refresh-issue
- forecastWorker: UPDATE event for each milestone auto-completed with isCompleted change
- All calls use .catch(() => {}) pattern — best-effort, never blocks jobs

* fix(260321-fk3): correct jobId reference in testmoImportWorker audit event

- Use jobId (string parameter) instead of job.id (BullMQ Job not in scope)
- processImportMode function receives jobId as parameter, not the BullMQ Job object

* docs(260321-fk3): complete add-audit-logging-to-workers plan

- SUMMARY.md with task commits, deviations, and decisions

* docs(quick-260321-fk3): Fix issue #143 — add audit logging to workers

* fix: add useCountProjects mock to Cases.test.tsx

Missing mock caused all 15 Cases component tests to crash during render.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* perf: skip forecast DB writes when values have not changed

- updateRepositoryCaseForecast: fetch current values, only update if different
- updateTestRunForecast: compare before writing for both clear and set paths
- Reduces unnecessary DB writes during scheduled forecast recalculations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: resume milestone v2.0 Comprehensive Test Coverage

* docs: mark v2.0 phases 10-24 complete in roadmap

* test: add AttachmentsCarousel component tests (REPO-11)

12 tests covering rendering, metadata display, edit mode,
navigation, delete popover, and canEdit toggle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: complete v2.0 Comprehensive Test Coverage milestone

Archive v2.0 (phases 9-24): 16 phases, 44 plans covering E2E tests,
component tests, API route tests, hooks, and workers. Also marks
v0.17.0 Copy/Move (phases 28-33) as shipped. Collapses ROADMAP.md
from 538 to 84 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: rename variables for consistency in tests

- Updated variable names in test files to prefix with an underscore for clarity and consistency.
- Adjusted notification text formatting in NotificationContent component for improved readability.
- Removed commented-out code in CopyMoveDialog test for cleaner codebase.

* test: update AttachmentsCarousel tests and refactor copy-move endpoint tests

- Added type definitions for attachments in AttachmentsCarousel tests for better type safety.
- Refactored variable names in copy-move endpoint tests for consistency and clarity.
- Updated test case creation to use new variable naming conventions, improving readability and maintainability.

* test: add mock for useCountProjects in Cases.test.tsx

- Introduced a mock for the useCountProjects hook to enhance test coverage and ensure consistent behavior during testing.

* chore: update CLI dependency installation in CI workflow

- Modified the CI workflow to include the --ignore-scripts flag during CLI dependency installation, ensuring that scripts are not executed during the install process.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: start milestone v0.17.0 Per-Prompt LLM Configuration

* docs: define milestone v0.17.0 requirements

* docs: create milestone v0.17.0 roadmap (6 phases)

* docs(34): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(34-schema-and-migration): create phase plan

* docs(34): plan phase 34 — schema and migration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(34-01): add llmIntegrationId and modelOverride fields to PromptConfigPrompt

- Add optional llmIntegrationId Int? FK field to PromptConfigPrompt
- Add LlmIntegration? relation on PromptConfigPrompt (no cascade delete)
- Add optional modelOverride String? field to PromptConfigPrompt
- Add @@index([llmIntegrationId]) on PromptConfigPrompt
- Add promptConfigPrompts[] reverse relation to LlmIntegration

* feat(34-01): regenerate ZenStack/Prisma artifacts with new PromptConfigPrompt fields

- prisma/schema.prisma updated with llmIntegrationId and modelOverride on PromptConfigPrompt
- lib/hooks regenerated with new relation hooks
- OpenAPI spec updated
- Database synced with new columns, FK constraint, and index

* docs(phase-34): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(35): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(35-resolution-chain): create phase plan

* docs(35): plan phase 35 — resolution chain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(35-01): extend PromptResolver and add LlmManager.resolveIntegration

- Add llmIntegrationId and modelOverride optional fields to ResolvedPrompt interface
- Populate these fields from PromptConfigPrompt in project-specific and default branches
- Add resolveIntegration() to LlmManager implementing 3-tier chain:
  1. Project LlmFeatureConfig override (highest priority)
  2. Per-prompt PromptConfigPrompt.llmIntegrationId
  3. Project default integration (getProjectIntegration)
- Add tests for per-prompt LLM fields in ResolvedPrompt

* feat(35-01): update all call sites to use resolveIntegration chain

- tag-analysis.service: replace getProjectIntegration with resolveIntegration (3-tier chain)
- generate-test-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- magic-select-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- parse-markdown-test-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- export/ai-stream/route: use resolveIntegration, pass resolved.model to LlmRequest
- aiExportActions: use resolveIntegration in both generateAiExportBatch and generateAiExport
- tag-analysis.service.test: add resolveIntegration mock, update no-integration test
- Explicit-integration endpoints (chat, test, admin chat) intentionally unchanged

* docs(35-01): complete resolution-chain plan — 3-tier LLM integration chain with 6 call sites updated

* docs(phase-35): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(36,37): smart discuss context for admin UI and project overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(37-project-ai-models-overrides): create phase plan

* docs(36-admin-prompt-editor-llm-selector): create phase plan

* docs(36,37): plan phases 36 and 37 — admin UI and project overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(36-01): add LLM integration and model override selectors to PromptFeatureSection

- Import useFindManyLlmIntegration and Select components
- Fetch active integrations with llmProviderConfig
- Derive availableModels from selected integration providerConfig
- Add integration selector with Project Default placeholder and clear option
- Add model override selector disabled when no integration selected
- Add en-US.json translation keys for new selectors

* feat(36-02): add mixed-integration indicator column to prompt config table

- Add llmIntegrations column to columns.tsx showing Project Default, single name, or N LLMs badge
- Rename unused _t param to t in getColumns, use it in new column
- Add PromptConfigPromptWithIntegration interface for typed llmIntegration relation
- Update both useFindManyPromptConfig queries in page.tsx to include llmIntegration relation

* feat(36-01): wire llmIntegrationId and modelOverride into Add and Edit form schemas and submit handlers

- Add llmIntegrationId and modelOverride to createFormSchema in both dialogs
- Add null defaults for new fields in getDefaultPromptValues (Add)
- Update useEffect in Edit to populate fields from existing prompt data
- Update createPromptConfigPrompt call to pass new fields when set
- Update updatePromptConfigPrompt call to include both fields on save

* feat(37-01): integrate FeatureOverrides into AI Models settings page

- Import FeatureOverrides from ./feature-overrides
- Render FeatureOverrides as a third card section after Prompt Configuration
- Wire projectId, integrations, projectDefaultIntegration, and promptConfigId props

* docs(36-02): complete mixed-integration indicator column plan

- 36-02-SUMMARY.md (in .planning, gitignored but tracked via state files)
- STATE.md updated with decision and progress
- ROADMAP.md phase 36 marked complete (2/2 plans with summaries)
- REQUIREMENTS.md ADMIN-03 marked complete

* docs(36-01): complete admin prompt editor LLM selector plan

- Add 36-01-SUMMARY.md with task details and decisions
- Update STATE.md: position advanced to phase 36 plan 01 complete
- Update ROADMAP.md: phase 36 progress updated
- Mark ADMIN-01 and ADMIN-02 requirements complete

* docs(37-01): complete per-feature LLM overrides plan — FeatureOverrides component integrated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(phase-36,37): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(38): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(38): create phase plan

* docs(38): plan phase 38 — export/import and testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(38-02): add resolveIntegration unit tests for 3-tier resolution chain

- Add llmFeatureConfig and projectLlmIntegration to createMockPrisma
- Add resolveIntegration describe block with 12 tests covering:
  - Level 1 LlmFeatureConfig active, model, null model, deleted, inactive, null relation
  - Level 2 per-prompt with modelOverride, without modelOverride, inactive fallthrough
  - Level 3 project default and system default fallback
  - Null return when no integration found at any level

* feat(38-01): create prompt config export API route

- GET /api/admin/prompt-configs/export?id=xxx
- Returns JSON with name, description, isDefault, isActive, prompts
- Each prompt includes feature, systemPrompt, userPrompt, temperature, maxOutputTokens, llmIntegrationName (human-readable), modelOverride
- Requires ADMIN auth, returns 400 for missing id, 404 for not found
- 13 unit tests covering auth, validation, and export behavior

* docs(38-02): complete resolveIntegration unit tests plan

- Create 38-02-SUMMARY.md documenting 12 resolveIntegration tests
- Update STATE.md with position and decisions
- Update ROADMAP.md phase 38 progress
- Mark TEST-01, TEST-02 requirements complete

* feat(38-01): create prompt config import API route

- POST /api/admin/prompt-configs/import
- Validates body with Zod schema (name required, prompts array required)
- Fetches active LLM integrations to resolve llmIntegrationName to llmIntegrationId
- Gracefully handles unresolved integration names (sets to null, reports in response)
- Preserves modelOverride as-is from import payload
- Returns 201 with created config id, name, and unresolvedIntegrations array
- 16 unit tests covering auth, validation, resolution, and graceful degradation

* docs(38-01): complete prompt config export/import plan

- SUMMARY.md: export/import API routes with LLM field portability
- STATE.md: decisions from 38-01, updated progress
- ROADMAP.md: phase 38 progress updated
- REQUIREMENTS.md: EXPORT-01 marked complete

* feat(38-03): add E2E tests for admin prompt editor LLM selector

- Test: select LLM integration for a prompt feature, save, and verify persistence after reload
- Test: clear LLM integration (select Project Default), save, and verify cleared after reload
- Uses API fixtures to create prompt config and LLM integration for setup
- Uses PromptConfigurationsPage page object for navigation and dialog interaction
- Selects "Project Default (clear)" option (matches en-US translation for __clear__ sentinel)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(38-03): add E2E tests for project AI Models per-feature overrides

- Test: feature overrides table displays all 7 LLM features
- Test: assign per-feature LLM override, verify effective LLM and Project Override badge
- Test: clear per-feature override, verify badge and clear button disappear
- Creates project via api.createProject() for valid projectId (not hardcoded fixture)
- Links LLM to project via api.linkLlmToProject() before testing override select
- Pre-assigns override via API for the clear test to avoid manual UI setup steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(38-03): complete prompt LLM selector and AI models overrides E2E tests plan

- SUMMARY.md: 2 tasks, 2 files created, 2 auto-fixed deviations documented
- STATE.md: decisions added for projectId fixture and __clear__ sentinel translation
- ROADMAP.md: phase 38 marked complete (3/3 summaries)
- REQUIREMENTS.md: TEST-03 and TEST-04 marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(phase-38): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39-documentation): create phase plan

* docs(39): plan phase 39 — documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39-01): add per-prompt LLM assignment section to prompt-configurations.md

- Add Per-Prompt LLM Assignment section with setup instructions and behavior notes
- Update Creating a Configuration step 3 to list LLM Integration and Model Override selectors
- Add cross-reference to AI Models LLM Resolution Chain

* docs(39-01): add per-feature overrides and resolution chain to llm-integrations.md

- Add Per-Feature LLM Overrides section with setup instructions and source badge reference
- Add LLM Resolution Chain section with three-level priority diagram
- Update Project Assignment to mention per-feature override capability
- Add cross-reference to prompt-configurations per-prompt LLM assignment

* docs(39-01): complete documentation plan — update planning state and summaries

- Update STATE.md: phase 39 complete, plan 39-01 complete, decisions recorded
- Update ROADMAP.md: phase 39 marked complete (1/1)
- Update REQUIREMENTS.md: DOCS-01 and DOCS-02 marked complete

* docs(phase-39): complete phase execution — all phases done

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update build artifacts

* feat: show LLM integration name in prompt feature accordion title

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: show 'Project Default' in accordion title when no LLM assigned

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve lint errors — jsx literals, unused vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove unused baseURL from E2E test destructuring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove duplicate useCountProjects mock in Cases.test.tsx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@therealbrad therealbrad changed the title Release v0.17.0 — adds two major features: **Copy/Move Test Cases Between Projects** and **Per-Prompt LLM Configuration**, along with worker audit logging, comprehensive test coverage improvements, and bug fixes. Release v0.17.0 — adds two major features: Copy/Move Test Cases Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes Mar 22, 2026
@therealbrad therealbrad changed the title Release v0.17.0 — adds two major features: Copy/Move Test Cases Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes feat: Release v0.17.0 — adds two major features: Copy/Move Test Cases Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes Mar 22, 2026
@therealbrad therealbrad merged commit 4116cb7 into main Mar 22, 2026
5 checks passed
@therealbrad therealbrad deleted the v0.17.0 branch March 22, 2026 03:25
@therealbrad
Copy link
Contributor Author

🎉 This PR is included in version 0.17.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

1 participant